Sipser CH2 PROBLEMS'ANSWER 1-5
2.18
- Let
be a context-free language and be a regular language. Let be the PDA that recognizes , and be the DFA that recognizes . If is the set of states of and is the set of states of , we construct a PDA that recognizes with the set of states . will do what does and also keep track of the states of . It accepts a string if and only if it stops at a state , where is the set of accept states of and is the set of accept states of . Since is recognized by , it is context free. - Let
be the regular language . If were a CFL then would be a CFL by part (a). However, , and Example 2.36 proves that is not context free. Thus is not a CFL.
2.19
The language
2.20
设
我们构造新的 PDA
- 状态集
: 的状态集包含 的所有原始状态,以及一组用于“验证”阶段的复合状态。 - 起始状态
: 的起始状态与 的起始状态相同。 - 接受状态集
: 的接受状态是这样一种复合状态:其中 的部分处于接受状态,同时 的部分也处于接受状态。 - 转移函数
: 转移函数包含三个部分,对应我们之前描述的两个阶段以及它们之间的切换。- 阶段一的转移(读取
): 对于任何在 中的输入符号 , 模拟 的行为。 如果 ,其中 ,那么我们在 中加入同样的转移: - 从阶段一到阶段二的切换: 当输入字符串
读取完毕后, 可以随时通过一个 -转移进入验证阶段。 对于 中的任意一个状态 ,我们添加一条 -转移,不改变栈的内容,进入一个复合状态。这个复合状态的第二部分是 的起始状态 ,因为对 的模拟需要从头开始。 - 阶段二的转移(验证
): 在验证阶段,所有转移都是 -转移。每一步 -转移都代表猜测 中的一个字符 。 对于任意复合状态 ,以及任意字符 : 如果 有一个转移 ,并且 有一个转移 , 那么我们就在 中添加一条相应的 -转移:
- 阶段一的转移(读取
工作原理解释
- 当
得到输入 时,它首先使用规则 (a) 来处理 。这个过程完全模拟了 的行为。在 被完全读取后,假设 的模拟到达了某个状态 。 - 此时,
可以使用规则 (b) 进行一次非确定性的 -转移,从状态 跳转到复合状态 ,并进入验证阶段。 - 在验证阶段,
进行一系列的 -转移(规则 c)。每一次这样的转移都对应于非确定性地选择一个字符 ,并同时更新 的模拟状态(从 到 )和 的模拟状态(从 到 )。 - 如果存在一串非确定性的选择(即一串字符
),使得 的模拟从 最终到达了某个接受状态 (这表明 ),并且 的模拟从状态 最终也到达了某个接受状态 (这表明 ),那么 将会到达复合状态 。 - 根据我们的定义,
是 的一个接受状态。因此,输入字符串 被接受。
2.21
该语言
一、上下文无关文法 (CFG)
我们提出的上下文无关文法
二、正确性证明
证明分为两部分:可靠性 (Soundness) 和 完备性 (Completeness)。
1. 可靠性证明 ( )
目标:证明由文法
基础情况: 派生长度为 1。
。对于 , ,满足 。归纳假设: 假设所有派生长度小于
的派生所生成的字符串 都满足 。归纳步骤: 考虑长度为
的派生。- 若第一步为
,则 。 的派生长度小于 ,由归纳假设, 且 。因此, 。 - 若第一步为
,则 。 满足归纳假设。因此: 显然, 。 - 对于规则
和 ,可以通过完全相同的代数运算验证该性质得以保持。
- 若第一步为
因此,所有由
2. 完备性证明 ( )
目标:证明语言
基础情况:
。则 。可以通过规则 生成。归纳假设: 假设所有在
中且长度小于 的字符串 都可以由 生成 ( )。归纳步骤: 考虑
且 。- 情况 A:
是可分解的 (Decomposable) 若 能被分解为 ,其中 均为 中的非空字符串。因为 且 ,根据归纳假设, 且 。因此,可以使用规则 生成 : 。 - 情况 B:
是不可分解的 (Indecomposable) 若 不可分解,意味着对于 的任何非空真前缀 ,都有 (即 )。若
以 ' ' 开头: 的形式必然是 或 。- 计算
的特征值:若 ,则 ;若 ,则 。 - 对
进行分解:令 是 的最长的、属于 的前缀 ( )。将 写为 。 - 分析剩余部分
:由于 的最长性, 没有任何非空前缀属于 。- 当
时, 必须以 开头,可写作 ,解得 ,即 。 - 当
时, 必须以 开头,可写作 ,解得 ,即 。
- 当
- 还原 w 的结构:
变为 ,对应规则 变为 ,对应规则
- 计算
如果
以 ' ' 开头: 。则 ,所以 。对于 的任何真前缀 (其中 是 的前缀), 。考虑在
中,函数 的值从 变化到 。因为函数值的变化步长为 +1 (遇到'a') 或 -2 (遇到'b'),所以路径上必然存在一点,使得函数值等于1。令 是 的最短的非空前缀,满足 。这个
必须以 'a' 结尾(否则 值无法从0或负数精确到达1)。所以 ,其中 。所以 。 现在我们有 。代入 可得 。对
应用同样的逻辑,它必须以 'a' 结尾,即 ,其中 。所以 。因此,我们证明了
,其中 。这意味着
。根据归纳假设, 和 。所以我们可以生成 : 。
- 情况 A:
在不可分解的所有情况下,
2.22
问题: 证明语言
证明:
我们可以将语言
这个语言(字符串长度不相等)是上下文无关的,因为我们可以构造一个确定性下推自动机(DPDA)来接受它:- 读取 # 左边的
,每读一个符号就向栈中推入一个标记。 - 读取 # 右边的
,每读一个符号就弹出一个标记。 - 如果输入结束时,栈不为空(
),则受理。 - 如果在读取
的过程中栈已变空但 仍有剩余( ),则受理。 因此, 是上下文无关语言。
- 读取 # 左边的
这个语言(长度相等但内容不同)也是上下文无关的,因为我们可以构造一个非决定性下推自动机(NPDA)来接受它:且 NPDA 非决定性地猜测一个位置
,并认定 和 在该位置的字符不同( )。执行逻辑:
- 自动机读取
的前 个字符,但不使用栈。 - 读取第
个字符 ,并利用有限状态(例如,转移到“记忆0”或“记忆1”等特定状态)将其“记忆”下来。 - 读取
的后缀( 之后的所有字符),每读一个字符就向栈中推入一个标记。 - 读取 # ,然后读取 的前
个字符,同样不使用栈。 - 读取
的第 个字符 ,并与状态中记忆的 比较。如果两者相同,则此路不通;如果不同,则继续。 - 读取
的后缀,每读一个字符就从栈中弹出一个标记。
- 自动机读取
如果输入结束时栈正好变空,说明
和 的前后缀长度均对应相等,总长度也相等,且在位置 存在不匹配。因此,字符串被受理。所以,
是上下文无关语言。
因为